home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / fstab / partition.c < prev   
C/C++ Source or Header  |  1996-03-01  |  5KB  |  281 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "../misc/misc.h"
  5. #include "../netconf/netconf.h"
  6. #include "fstab.h"
  7. #include "fstab.m"
  8.  
  9. /*
  10.     describe one entry of the partition table
  11. */
  12. PUBLIC PARTITION::PARTITION(
  13.     const char *_dev,
  14.     int _id,
  15.     long _size)
  16. {
  17.     dev =strdup_err(_dev);
  18.     id = _id;
  19.     size = _size;
  20.     drive_letter = ' ';
  21.  
  22. PUBLIC PARTITION::~PARTITION()
  23. {
  24.     free (dev);
  25. }
  26.  
  27. /*
  28.     Set the drive letter DOS would normally associate with this
  29.     partition.
  30. */
  31. PUBLIC void PARTITION::setdosdrive(char letter)
  32. {
  33.     drive_letter = letter;
  34. }
  35. /*
  36.     Get the drive letter DOS would normally associate with this
  37.     partition.
  38. */
  39. PUBLIC char PARTITION::getdosdrive()
  40. {
  41.     return drive_letter;
  42. }
  43.  
  44. /*
  45.     Return != 0 if the partition is a DOS one.
  46. */
  47. PUBLIC int PARTITION::isdos()
  48. {
  49.     return id == PARTITION_DOS_ID12
  50.         || id == PARTITION_DOS_ID16
  51.         || id == PARTITION_DOS_ID1632;
  52. }
  53. /*
  54.     Return != 0 if the partition is a OS/2 one.
  55. */
  56. PUBLIC int PARTITION::isos2()
  57. {
  58.     return id == PARTITION_OS2_HPFS;
  59. }
  60.  
  61. /*
  62.     Return != if a partition is a swap.
  63. */
  64. PUBLIC int PARTITION::isswap()
  65. {
  66.     return id == PARTITION_LINUX_SWAP;
  67. }
  68. /*
  69.     Return != if a partition is a native linux one (ext2).
  70. */
  71. PUBLIC int PARTITION::islinux()
  72. {
  73.     /* #Specification: fsconf / partition / linux native
  74.         fsconf does not differentiate minix / xiafs / ext and
  75.         ext2 partition. It assumes that a "Linux native"
  76.         partition is always a ext2 one.
  77.     */
  78.     return id == PARTITION_LINUX_NATIVE;
  79. }
  80.  
  81.  
  82. /*
  83.     Return the path of the device controlling a partition.
  84. */
  85. PUBLIC const char *PARTITION::getdevice()
  86. {
  87.     return dev;
  88. }
  89.  
  90. /*
  91.     Return the size (in block) of the partition
  92. */
  93. PUBLIC long PARTITION::getsize()
  94. {
  95.     return size;
  96. }
  97.  
  98. /*
  99.     Return the ID (in block) of the partition
  100. */
  101. PUBLIC int PARTITION::getid()
  102. {
  103.     return id;
  104. }
  105.  
  106. PUBLIC void PARTITION::formatinfo(char *buf)
  107. {
  108.     char drive[3];
  109.     drive[0] = '\0';
  110.     if (drive_letter != ' '){
  111.         sprintf (drive,"%c:",drive_letter);
  112.     }
  113.     sprintf (buf,"%7ldM %-5s(%02x) %s"
  114.         ,size/1024,getos()
  115.         ,id,drive);
  116. }
  117.  
  118. /*
  119.     Return the name of the OS related to this partition if it is a
  120.     filesystem.
  121.  
  122.     Return "" is unknown
  123. */
  124. PUBLIC const char *PARTITION::getos()
  125. {
  126.     char *ret = "";
  127.     if (isdos()){
  128.         ret = "Dos";
  129.     }else if (islinux()){
  130.         ret = "Linux";
  131.     }else if (isswap()){
  132.         ret = "Swap";
  133.     }else if (isos2()){
  134.         ret = "Os/2";
  135.     }
  136.     return ret;
  137. }
  138.  
  139. PUBLIC PARTITIONS::PARTITIONS()
  140. {
  141.     DAEMON *dae = daemon_find ("fdisk");
  142.     if (dae != NULL){
  143.         char cmd[200];
  144.         sprintf (cmd,"%s -l",dae->getpath());
  145.         FILE *fin = popen (cmd,"r");
  146.         if (fin != NULL){
  147.             char buf[300];
  148.             while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
  149.                 if(buf[0] == '/'){
  150.                     char t[7][30];
  151.                     int nb = sscanf (buf
  152.                         ,"%s %s %s %s %s %s %s"
  153.                         ,t[0],t[1],t[2],t[3],t[4],t[5]
  154.                         ,t[6]);
  155.                     if (nb != 7){
  156.                         xconf_error (
  157.                             MSG_U(E_IVLDFDISK
  158.                             ,"Invalid output format for fdisk\n%s")
  159.                             ,buf);
  160.                     }else{
  161.                         int offset = 4;
  162.                         if(strcmp(t[1],"*")==0) offset = 5;
  163.                         int id;
  164.                         sscanf (t[offset+1],"%x",&id);
  165.                         add (new PARTITION(t[0],id
  166.                             ,atoi(t[offset])));
  167.                     }
  168.                 }
  169.             }
  170.         }
  171.         pclose (fin);
  172.     }
  173.     setdosdrive();
  174. }
  175.  
  176. PUBLIC PARTITION *PARTITIONS::getitem(int no) const
  177. {
  178.     return (PARTITION*)ARRAY::getitem(no);
  179. }
  180.  
  181. /*
  182.     Locate one partition in the table using its device path as key.
  183.     Return NULL if not found.
  184. */
  185. PUBLIC PARTITION *PARTITIONS::getitem(const char *device) const
  186. {
  187.     PARTITION *ret = NULL;
  188.     for (int i=0; i<getnb(); i++){
  189.         PARTITION *p = getitem(i);
  190.         if (strcmp(p->getdevice(),device)==0){
  191.             ret = p;
  192.             break;
  193.         }
  194.     }
  195.     return ret;
  196. }
  197.  
  198. /*
  199.     Assign DOS drive letter to DOS partition
  200. */
  201. PROTECTED void PARTITIONS::setdosdrive()
  202. {
  203.     /* #Specification: partitions / dos drive / how it works
  204.         All this is very complicate.
  205.  
  206.         DOS allocate C on the first non extended DOS partition
  207.         of the first drive.
  208.  
  209.         It then allocate D if possible on the first non extended
  210.         DOS partition of the second drive.
  211.  
  212.         From there is get back to the first drive and allocate
  213.         a letter to all DOS extended partition. After that
  214.         it goes and finished the second hard drive.
  215.  
  216.         I have no idea what happen when you get more than
  217.         four drives. DOS does not support it if I am right.
  218.         Some info is needed here.
  219.     */
  220.     char drive = 'C';
  221.     char minpart = '1';
  222.     char maxpart = '4';
  223.     for (int pass=0; pass<2; pass++){
  224.         for (int d='a'; d<='b'; d++){
  225.             for (int i=minpart; i<=maxpart; i++){
  226.                 char buf[10];
  227.                 sprintf (buf,"/dev/hd%c%c",d,i);
  228.                 PARTITION *p = getitem (buf);
  229.                 if (p != NULL
  230.                     && p->isdos()){
  231.                     p->setdosdrive(drive);
  232.                     drive++;
  233.                     if (pass == 0) break;
  234.                 }
  235.             }
  236.         }
  237.         minpart = '5';
  238.         maxpart = '8';
  239.     }
  240. }
  241.  
  242. /*
  243.     Probe the partition table of all devices.
  244.     This take some time since fdisk is spawned to get it. So the
  245.     result is kept from call to call.
  246.     
  247.     The returned object should not be deleted.
  248. */
  249. PARTITIONS *partition_load()
  250. {
  251.     static PARTITIONS *parts = NULL;
  252.     if (parts == NULL){
  253.         parts = new PARTITIONS;
  254.     }
  255.     return parts;
  256. }
  257.  
  258. #ifdef TEST
  259.  
  260. int main (int , char *[])
  261. {
  262.     PARTITIONS parts;
  263.     for (int i=0; i<parts.getnb(); i++){
  264.         PARTITION *p = parts.getitem(i);
  265.         char *type = "???";
  266.         if (p->isswap()){
  267.             type = "Swap";
  268.         }else if (p->isdos()){
  269.             type = "Dos";
  270.         }else if (p->islinux()){
  271.             type = "Linux";
  272.         }
  273.         printf ("%s %ld %s\n",p->getdevice(),p->getsize()
  274.             ,type);
  275.     }
  276.     return 0;
  277. }
  278.  
  279. #endif
  280.